package com.ctshk.rpc.order.goods.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.constant.RedisConstants;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.SystemError;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.common.model.PageResponse;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.common.utils.RSAUtil;
import com.ctshk.rpc.order.goods.dto.OrderShopCustomerDTO;
import com.ctshk.rpc.order.goods.dto.ShoppingShopStoreDTO;
import com.ctshk.rpc.order.goods.entity.ShoppingShopStore;
import com.ctshk.rpc.order.goods.entity.ShoppingShopStoreUser;
import com.ctshk.rpc.order.goods.mapper.ShoppingShopStoreMapper;
import com.ctshk.rpc.order.goods.mapper.ShoppingShopStoreUserMapper;
import com.ctshk.rpc.order.goods.req.OrderShopCustomerReq;
import com.ctshk.rpc.order.goods.req.ShoppingShopLoginReq;
import com.ctshk.rpc.order.goods.req.ShoppingShopPwdLoginReq;
import com.ctshk.rpc.order.goods.req.SmsCaptchaReq;
import com.ctshk.rpc.order.goods.service.IShoppingShopStoreUserService;
import com.ctshk.rpc.system.service.ISysUserService;
import com.ctshk.rpc.user.dto.AppUserDTO;
import com.ctshk.rpc.user.dto.es.OrderEsDTO;
import com.ctshk.rpc.user.req.OrderPageReq;
import com.ctshk.rpc.user.service.IOrderEsService;
import com.ctshk.rpc.user.service.IUserService;
import com.ctshk.rpc.user.service.IUserValidateService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>
 * 小店用户管理--服务实现
 * </p>
 *
 * @author 黄利斌
 * @date 2021/6/2 11:16 上午
 */
@Slf4j
@DubboService
public class ShoppingShopStoreUserServiceImpl extends ServiceImpl<ShoppingShopStoreUserMapper, ShoppingShopStoreUser> implements IShoppingShopStoreUserService {

    @DubboReference
    private IUserValidateService userValidateService;

    @Autowired
    private ShoppingShopStoreMapper shoppingShopStoreMapper;

    @Autowired
    private ShoppingShopStoreUserMapper shoppingShopStoreUserMapper;

    @DubboReference
    private ISysUserService sysUserService;

    @DubboReference
    private IUserService userService;

    @DubboReference
    private IOrderEsService orderEsService;


    @Override
    public Result<PageResponse<OrderShopCustomerDTO>> customerStatistics(OrderShopCustomerReq req, ShoppingShopStoreDTO shoppingShopStoreDTO) {
        log.info("【中旅小店--小店客户统计--start】，入参为 -- OrderShopCustomerReq:{},ShoppingShopStoreDTO:{}",JSON.toJSONString(req),JSON.toJSONString(shoppingShopStoreDTO));
        List<OrderShopCustomerDTO> orderShopCustomerDTOList = new ArrayList<>();
        List<OrderShopCustomerDTO> orderShopCustomerDTOList2 = new ArrayList<>();
        OrderShopCustomerDTO orderShopCustomerDTO = null;

        OrderPageReq orderPageReq = new OrderPageReq();
        List<Integer> typeList = new ArrayList<>();
        typeList.add(18);
        orderPageReq.setTypeList(typeList);
        orderPageReq.setShopId(req.getShopId());
        orderPageReq.setGmtCreateType(null);
        try {
            Result<PageResponse<OrderEsDTO>> pageResponseResult = orderEsService.queryPage(orderPageReq);
            if (pageResponseResult.getCode() == 0 && pageResponseResult.getMsg().equalsIgnoreCase("成功")) {
                PageResponse<OrderEsDTO> pageResponseResultData = pageResponseResult.getData();
                Map<Object, Object> map = new HashMap<Object, Object>();
                if (CollectionUtils.isNotEmpty(pageResponseResultData.getRecords())) {
                    for (OrderEsDTO record : pageResponseResultData.getRecords()) {
                        // 统计总金额
                        if (map.containsKey(record.getUserId())) {
                            BigDecimal value = new BigDecimal(map.get(record.getUserId()).toString());
                            value.add(record.getOrderAmount());
                            map.put(record.getUserId(), value);
                        } else {
                            map.put(record.getUserId(), record.getOrderAmount());
                        }
                        AppUserDTO userDTO = userService.queryCacheUser(record.getUserId());
                        orderShopCustomerDTO = EntityUtil.copy(userDTO, OrderShopCustomerDTO.class);
                        orderShopCustomerDTOList.add(orderShopCustomerDTO);
                    }
                    for (OrderShopCustomerDTO shopCustomerDTO : orderShopCustomerDTOList) {
                        if (map.containsKey(shopCustomerDTO.getId())) {
                            shopCustomerDTO.setTotalMoney(new BigDecimal(map.get(shopCustomerDTO.getId()).toString()));
                            orderShopCustomerDTOList2.add(shopCustomerDTO);
                        }
                    }
                    Page<OrderShopCustomerDTO> iPage = new Page<>(req.getPageNo(), req.getPageSize());
                    PageResponse<OrderShopCustomerDTO> response = new PageResponse<>(orderShopCustomerDTOList2, iPage.getCurrent() == 1, orderShopCustomerDTOList2.size() <= (iPage.getCurrent() * iPage.getSize()), orderShopCustomerDTOList2.size(), iPage.getCurrent(), iPage.getSize());
                    return Result.success(response);
                }
            }
        } catch (Exception e) {
            log.error("中旅小店--查询小店销售数据失败-----错误为：{}", e.getMessage());
        }
        log.info("【中旅小店--小店客户统计--end】");
        return Result.success(null);
    }

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public Result updatePwd(SmsCaptchaReq req) {
        log.info("【中旅小店--更新密码--start】，入参为：{}",JSON.toJSONString(req));
        //校验验证码
        try {
            boolean checkCode = userValidateService.checkCode(req.getContactMobileAreaCode(), req.getContactNumber(), req.getCode());
            if (!checkCode) {
                throw new BusinessException(SystemError.SYS_435);
            }
        } catch (Exception e) {
            throw new BusinessException(SystemError.SYS_435);
        }
        // 根据手机号码查询小店信息
        ShoppingShopStore shoppingShopStore = shoppingShopStoreMapper.selectShopByPhone(req.getContactNumber());
        if (null == shoppingShopStore) {
            throw new BusinessException(SystemError.GOODS_SHOP_ERROR_40010);
        }
        // 更新小店密码
        shoppingShopStore.setPassword(req.getPassword());
        shoppingShopStoreMapper.updateById(shoppingShopStore);
        ShoppingShopStoreDTO shoppingShopStoreDTO = EntityUtil.copy(shoppingShopStore, ShoppingShopStoreDTO.class);
        // 生成token信息，存储redis中
        String token = RSAUtil.encryptStr(JSONObject.toJSONString(shoppingShopStoreDTO));
        shoppingShopStoreDTO.setToken(token);
        String tokeyKey = RedisConstants.CLIENT_SHOP_TOKEN_USER_KEY+shoppingShopStoreDTO.getContactMobileAreaCode() + shoppingShopStoreDTO.getCustomerServiceHotline();
        log.info("【中旅小店--更新密码--redis存储token】，key：{},value:{}",tokeyKey,token);
        redisTemplate.opsForValue().set(tokeyKey, token, 7L, TimeUnit.DAYS);
        log.info("【中旅小店--更新密码--end】");
        return Result.success(token);
    }

    /**
     * redis中是否存在key
     *
     * @param key
     * @return
     */
    private boolean hasKey(String key) {
        return redisTemplate.hasKey(key);
    }

    @Override
    public Result<ShoppingShopStoreDTO> loginAndCode(ShoppingShopLoginReq req) {
        log.info("【中旅小店--验证码登录--start】，入参为：{}",JSON.toJSONString(req));
        //校验验证码
        try {
            boolean checkCode = userValidateService.checkCode(req.getContactMobileAreaCode(), req.getContactNumber(), req.getCode());
            if (!checkCode) {
                throw new BusinessException(SystemError.SYS_435);
            }
        } catch (Exception e) {
            throw new BusinessException(SystemError.SYS_435);
        }
        // 查询缓存中小店信息
//        ShoppingShopStoreDTO shoppingShopStoreDTO = JSON.parseObject(redisTemplate.opsForValue().get(RedisConstants.CLIENT_SHOP_TOKEN_USER_KEY + req.getContactMobileAreaCode() + req.getContactNumber()).toString(), ShoppingShopStoreDTO.class);
        ShoppingShopStoreDTO shoppingShopStoreDTO = null;
        if (hasKey(RedisConstants.CLIENT_SHOP_TOKEN_USER_KEY + req.getContactMobileAreaCode() + req.getContactNumber())){
            String token = JSON.parseObject(redisTemplate.opsForValue().get(RedisConstants.CLIENT_SHOP_TOKEN_USER_KEY + req.getContactMobileAreaCode() + req.getContactNumber()).toString(), ShoppingShopStoreDTO.class).toString();
            String tokenDecrypt = RSAUtil.decryptStr(token);
            shoppingShopStoreDTO = JSONObject.parseObject(tokenDecrypt, ShoppingShopStoreDTO.class);
        }
        if (null == shoppingShopStoreDTO) {
            // 根据手机号码查询小店
            ShoppingShopStore shoppingShopStore = shoppingShopStoreMapper.selectShopByPhone(req.getContactNumber());
            if (null == shoppingShopStore) {
                return Result.failed(SystemError.GOODS_SHOP_ERROR_40011);
            }
            shoppingShopStoreDTO = EntityUtil.copy(shoppingShopStore, ShoppingShopStoreDTO.class);
            // 生成token信息，存储redis中
            String token = RSAUtil.encryptStr(JSONObject.toJSONString(shoppingShopStoreDTO));
            String tokeyKey = RedisConstants.CLIENT_SHOP_TOKEN_USER_KEY + shoppingShopStoreDTO.getCustomerServiceHotline();
            shoppingShopStoreDTO.setToken(token);
            log.info("【中旅小店--验证码登录--redis存储token信息】，key：{},value：{}",tokeyKey,token);
            redisTemplate.opsForValue().set(tokeyKey, token, 7L, TimeUnit.DAYS);
            shoppingShopStoreDTO.setToken(token);
//            return Result.success(RedisConstants.JWT_TOKEN_PREFIX + Strings.EMPTY+ tokeyKey);
        }
        log.info("【中旅小店--验证码登录--end】");
        return Result.success(shoppingShopStoreDTO);
    }

    public static String emailReg = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$";
    public static String phoneReg = "^[0-9]+$";

    private boolean isMobile(String mobiles) {
        Pattern p = Pattern.compile("^1(3|5|7|8|4)\\d{9}");
        Matcher m = p.matcher(mobiles);
        return m.matches();
    }

    @Override
    public Result<ShoppingShopStoreDTO> loginAndPwd(ShoppingShopPwdLoginReq req) {
        log.info("【中旅小店--密码登录--start】，入参为：{}",JSON.toJSONString(req));
        if (StringUtils.isEmpty(req.getContactNumber()) || StringUtils.isEmpty(req.getPassword())) {
            return Result.failed(SystemError.SYS_402);
        }
        // 账户校验
        String contactNumber = req.getContactNumber();
        Pattern p = Pattern.compile("\\w{3,15}@(\\w{2,8}\\.){1,2}(com|net|cn)");
        Matcher m = p.matcher(contactNumber);

        ShoppingShopStore shoppingShopStore = shoppingShopStoreMapper.selectShopByPhoneOrEmail(req.getContactNumber());
        log.info("【中旅小店--密码登录--查询小店信息】，返参为：{}",JSON.toJSONString(shoppingShopStore));
        ShoppingShopStoreDTO shoppingShopStoreDTO = new ShoppingShopStoreDTO();
        if (null == shoppingShopStore){
            return Result.failed(SystemError.GOODS_SHOP_ERROR_40013);
        }else {
            // 手机号获取小店信息
            if (isMobile(contactNumber)) {
                shoppingShopStore = shoppingShopStoreMapper.selectShopByPhoneAndPassword(contactNumber,req.getPassword());
                // 电子邮箱获取小店信息
            } else if (m.matches()) {
                shoppingShopStore = shoppingShopStoreMapper.selectShopByEmail(contactNumber,req.getPassword());
            }
            if (null == shoppingShopStore) {
                return Result.failed(SystemError.GOODS_SHOP_ERROR_40011);
            }
            if (!shoppingShopStore.getPassword().equals(req.getPassword())) {
                return Result.failed(SystemError.GOODS_SHOP_ERROR_40015);
            }
            shoppingShopStoreDTO = EntityUtil.copy(shoppingShopStore, ShoppingShopStoreDTO.class);
            // 生成token信息，存储redis中
            String token = RSAUtil.encryptStr(JSONObject.toJSONString(shoppingShopStoreDTO));
            String tokeyKey = RedisConstants.CLIENT_SHOP_TOKEN_USER_KEY +shoppingShopStoreDTO.getContactMobileAreaCode()+ shoppingShopStoreDTO.getCustomerServiceHotline();
            shoppingShopStoreDTO.setToken(token);
            log.info("【中旅小店--密码登录--redis存储token】，入参为 -- key:{},value:{}",tokeyKey,token);
            redisTemplate.opsForValue().set(tokeyKey, token, 7L, TimeUnit.DAYS);
//            shoppingShopStoreDTO.setToken(token);
        }
        log.info("【中旅小店--密码登录--end】");
        return Result.success(shoppingShopStoreDTO);
    }
}
